﻿using System;
using System.Globalization;
using Jayden.Dll.Core.Persistence;
using Jayden.Dll.Entities.Common;
using Jayden.Dll.Web.Events;
using Jayden.Dll.Web.Helper;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.Json;

namespace Jayden.Dll.Web.Controls.Edit
{
	public class PostForm : Form
	{
		public delegate void OnPostSuccess(HttpHandlerContext context, Post user);

		public class PostCommandHandler : HttpCommandHandler
		{
			public PostCommandHandler() : this("Post") { }
			public PostCommandHandler(string command)
				: base(command)
			{
				RegisterEvent("PostSuccess");
			}
			public event OnPostSuccess PostSuccess { add { AddEvent<OnPostSuccess>("PostSuccess", value); } remove { RemoveEvent<OnPostSuccess>("PostSuccess", value); } }

			protected override void ProcessCommand(HttpHandlerContext context, string command)
			{
				string cultureCode = context.Request["cultureCode"];
				string title = context.Request["title"];
				string body = context.Request["content"];
				string author = context.Request["author"];
				long postId = 0;
				long.TryParse(context.Request["postId"], out postId);
				DateTime time = HtmlHelper.FromHtmlDateTime(context.Request["time"], DateTime.Now);

				PostDataAccess postDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<PostDataAccess, Post>();
				if (postDataAccess != null)
				{
					ObjectId oid = context.UnitOfWork.NewObjectId(postDataAccess.Entity, postId);
					Post post = null;
					if (postId == 0)
						post = context.UnitOfWork.NewObject<Post>(postDataAccess.Entity, oid);
					else
					{
						post = postDataAccess.Read(oid);
						if (post == null)
						{
							context.Logger.Fine("Trying to edit unknow post with id '{0}'.", postId);
							return;
						}
					}
					post.Body = body;
					post.CultureCode = cultureCode ?? context.Lang;
					post.Title = title;
					post.DateTime = time;
					post.Author = author;
					if (postId == 0)
					{
						post.UserName = context.IsAuthenticated ? context.UserName : null;
						post.CreationDate = DateTime.Now;
					}

					if (postId == 0)
						context.UnitOfWork.MarkNew(post);
					else
						context.UnitOfWork.MarkDirty(post);
					context.UnitOfWork.Commit();

					Invoke("PostSuccess", context, null);
				}
			}
		}

		private Select m_CultureCode;
		private Input m_Title;
		private Input m_Author;
		private Input m_Time;
		private Input m_PostId;
		private Textarea m_Content;

		private Button m_Post;

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			base.Load(node, loader);
			if (Id == null)
				Id = "postForm";
			m_CultureCode = GetFormElement<Select>("cultureCode");
			m_Title = GetFormElement<Input>("title");
			m_Content = GetFormElement<Textarea>("content");
			m_Author = GetFormElement<Input>("author");
			m_Time = GetFormElement<Input>("time");
			m_PostId = GetFormElement<Input>("postId");
			m_Post = GetFormElement<Button>("post", "command");
		}

		public void LoadPost(Post post, HtmlControlLoader loader = null)
		{
			if (m_CultureCode != null)
				m_CultureCode.SelectedValue = post.CultureCode;
			m_Title.Value = post.Title;
			m_Content.InnerText = post.Body;
			m_Author.Value = post.Author;
			m_Time.Value = HtmlHelper.ToHtmlDateTime(post.DateTime);
			m_PostId.Value = post.PostId.ToString();
		}


		private void FillFromConfiguration(HttpHandlerContext context)
		{
			if (m_CultureCode != null)
			{
				string[] langs = context.Configuration.GetValues("Languages/Lang/@lang");
				foreach (string lang in langs)
				{
					CultureInfo cultureInfo = new CultureInfo(lang);
					m_CultureCode.AddOption(lang, cultureInfo.EnglishName);
				}
			}
		}

		private void LoadFromContext(HttpHandlerContext context)
		{
			bool command = false;
			string postIdStr = context.Request["editPostId"];
			long postId = 0;
			if (postIdStr != null)
				long.TryParse(postIdStr, out postId);
			FillFromConfiguration(context);
			if (postId != 0)
			{
				PostDataAccess postDataAccess = context.UnitOfWork.DataAccessManager.GetDataAccess<PostDataAccess, Post>();
				if (postDataAccess != null)
				{
					ObjectId oid = context.UnitOfWork.NewObjectId(postDataAccess.Entity, postId);
					Post post = postDataAccess.Read(oid);
					if (post != null)
					{
						LoadPost(post, context.ControlLoader);
						command = true;
					}
				}
			}
			else
			{
				m_Time.Value = HtmlHelper.ToHtmlDateTime(DateTime.Now);
				m_Author.Value = context.Context.User.Identity.Name;
			}

			if (command && context.Json != null)
			{
				JsonObject form = new JsonObject();
				JsonObject values = new JsonObject();
				form.Add("values", values);
				form.Add("focus", m_Content.Id);
				context.Json.Add(Id, form);
				values.Add(m_Title.Id, m_Title.Value);
				values.Add(m_Content.Id, m_Content.InnerText);
				values.Add(m_Author.Id, m_Author.Value);
				values.Add(m_Time.Id, m_Time.Value);
				values.Add(m_PostId.Id, m_PostId.Value);
			}
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{
			ServerRender = (context.User != null && context.User.RoleNames.Contains("admin"));
			if (!ServerRender)
				return;
			LoadFromContext(context);
			PostCommandHandler handler = context.HandlerManager.GetHandler<PostCommandHandler>();
			handler.PostSuccess += new OnPostSuccess(PostSuccess);
			base.ProcessHtmlRequest(context);
		}

		public override void  ProcessJsonRequest(HttpHandlerContext context)
		{
			ServerRender = (context.User != null && context.User.RoleNames.Contains("admin"));
			if (!ServerRender)
				return;
			LoadFromContext(context);
			PostCommandHandler handler = context.HandlerManager.GetHandler<PostCommandHandler>();
			handler.PostSuccess += new OnPostSuccess(PostSuccess);
			base.ProcessHtmlRequest(context);
		}

		public override void ProcessJsRequest(HttpHandlerContext context)
		{
			base.ProcessJsRequest(context);
			string id = Id;
			context.Js[id].AppendAjaxSubmit(this, m_Post);
			context.Js[id].AppendAjaxHandler(@"
		if(data." + id + @") {
			if(data." + id + @".values) {
				var key;
				var $key;
				for (key in data." + id + @".values) {
					$key = $('#'+key);
					$key.val(data." + id + @".values[key]);
					if(!JAYDEN.html5.input.placeholder && $key.hasClass('placeholder'))
						$key.removeClass('placeholder');
				}
			}
			if(data." + id + @".focus) {
				$('#' + data." + id + @".focus).focus();
			}
		}
");
		}

		private void PostSuccess(HttpHandlerContext context, Post user)
		{
		}

	}
}
